<template>
  <div class="hor-layout-center">
    <div class="hor-layout-center prop-item last-item">
      <div class="prop-type">Object</div>
      <div class="prop-key single-line">{{ propKey }}</div>
      <i class="add-view el-icon-circle-plus" @click="addProp"></i>
      <i v-if="propKey" class="close-view el-icon-circle-close" @click="removeParentProp()"></i>
    </div>
    <div class="line-view"></div>
    <div class="ver-layout prop-layout">
      <div v-for="(item,index) in jsonList" :key="index">
        <div v-if="item.propType!='Object'" class="prop-item hor-layout-side-center" @click="editProp(item)">
          <div class="prop-type">{{ item.propType }}</div>
          <div class="prop-key single-line">{{ item.propKey }}</div>
          <div class="prop-value single-line">{{ item.propValue }}</div>
          <i class="close-view el-icon-circle-close" @click="removeProp(item)"></i>
        </div>
        <base-obj v-else :json-data="item.propValue" :prop-key="item.propKey" @removeParentProp="removeProp"
                  @objBack="objChildBack"></base-obj>
      </div>
    </div>
    <!--  添加属性弹窗  -->
    <el-dialog :visible.sync="showPropDialog" :title="propDialogTitle" width="300px" :append-to-body="true" center>
      <el-form v-model="propFormData" size="small" :rules="propFormRules">
        <el-form-item label="类型" prop="propType">
          <el-select v-model="propFormData.propType" style="width: 150px">
            <el-option v-for="(item,index) in propTypeOptions" :key="index" :label="item.label"
                       :value="item.value"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="属性名" prop="propKey" class="hor-layout">
          <el-input v-model="propFormData.propKey" type="text" style="width: 150px"></el-input>
        </el-form-item>
        <el-form-item label="属性值" prop="propValue" class="hor-layout">
          <el-input
              :disabled="propFormData.propType=='Object'||propFormData.propType=='Array'||propFormData.propType=='Boolean'"
              v-model="propFormData.propValue" type="text"
              style="width: 150px"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="info" size="small" @click="closeDialog">取消</el-button>
        <el-button type="primary" size="small" @click="saveData">保存</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
const getDataType = (data) => {
  return Object.prototype.toString.call(data).replace(/['\\[','\]']/g, "").split(" ")[1]
}
const generateId = () => {
  let color = "", letters = "01234567890ABCDEF"
  for (let i = 0; i < 5; i++) {
    color += letters[Math.floor(Math.random() * 16)]
  }
  return new Date().getTime() + color
}
export default {
  name: "base-obj",
  props: {
    jsonData: {
      type: Object
    },
    propKey: {
      type: String
    }
  },
  data() {
    return {
      jsonDataValue: {},
      jsonList: [],
      currentPropItem: "",
      showPropDialog: false,
      propFormOption: "",
      propFormRule: "",
      propTypeData: ['String', 'Number', 'Boolean', "Object", "Array"],
      propFormRules: {
        propType: [{required: true, message: '请输入活动名称', trigger: 'blur,change'},],
        propKey: [{required: true, message: '请输入活动名称', trigger: 'blur,change'},],
        propValue: [{required: true, message: '请输入活动名称', trigger: 'blur,change'},],
      },
      propFormData: {
        propType: "",
        propKey: "",
        propValue: ""
      }
    }
  },
  watch: {
    jsonData: {
      handler(val) {
        this.jsonDataValue = val
        this.jsonList = Object.entries(val).map(([key, value]) => {
          return {id: generateId(), propType: getDataType(value), propKey: key, propValue: value}
        })
      },
      immediate: true
    },
    "propFormData.propType": {
      handler(val) {
        if (val == "Object") this.propFormData.propValue = "{}"
        if (val == "Array") this.propFormData.propValue = "[]"
        if (val == "Boolean") this.propFormData.propValue = true
      }
    }
  },
  computed: {
    propTypeOptions() {
      return this.propTypeData.map(item => {
        return {label: item, value: item}
      })
    },
    propDialogTitle() {
      return this.currentPropItem ? "编辑属性值" : "新增属性值"
    }
  },
  methods: {
    addProp() {
      this.showPropDialog = true
      this.currentPropItem = ""
      this.$nextTick(() => {
        //清空表单数据
        this.propFormData = {}
      })
    },
    editProp(item) {
      this.currentPropItem = item
      this.showPropDialog = true
      this.$nextTick(() => {
        //表单赋值
        this.propFormData = {...item}
      })
    },
    removeProp(item) {
      this.jsonList = this.jsonList.filter(i => i.id != item.id)
      delete this.jsonDataValue[item.propKey]
      this.$emit("objBack", this.jsonDataValue, this.propKey)
    },
    removeParentProp() {
      this.$emit("removeParentProp", this.jsonData)
    },
    objChildBack(data, key) {
      this.jsonDataValue[key] = data
      this.$emit("objBack", this.jsonDataValue)
    },
    closeDialog() {
      this.showPropDialog = false
    },
    saveData() {
      let formData = this.propFormData//表单数据
      formData = {id: generateId(), ...formData}
      let {propKey, propValue, propType} = formData
      if (propType == "Object") propValue = {}
      if (propType == "Array") propValue = []
      if (propType == "Number") propValue = Number(propValue)
      formData = {propType, propKey, propValue}
      if (this.currentPropItem) {
        this.jsonList = this.jsonList.map(item => {
          if (item.id == this.currentPropItem.id) item = formData
          return item
        })
        delete this.jsonDataValue[this.currentPropItem.propKey]
      } else {
        this.jsonList.push(formData)
      }
      this.jsonDataValue[propKey] = propValue
      this.$emit("objBack", this.jsonDataValue, this.propKey)
      this.showPropDialog = false
    }
  }
}
</script>

<style scoped>
.hor-layout-center {
  display: flex;
  flex-direction: row;
  align-items: center;
}

.hor-layout-side-center {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
}

.ver-layout {
  display: flex;
  flex-direction: column;
}

.prop-layout {
  padding-left: 10px;
  border-top-left-radius: 7px;
  border-bottom-left-radius: 7px;
  border-left: 2px solid #5b5858;
}

.dropdown-view {
  margin-left: 10px;
}

.line-view {
  width: 21px;
  height: 2px;
  background-color: #5b5858;
}

.prop-item {
  position: relative;
  width: fit-content;
  margin-bottom: 10px;
  border: 1px solid #d1d1d1;
  border-radius: 4px;
}

.last-item {
  margin-bottom: 0px;
}

.prop-type {
  width: 50px;
  background-color: #d1ddff;
  font-size: 12px;
  border-radius: 4px 0 0 4px;
  color: #657c99;
  height: 20px;
  padding: 0 7px;
  display: flex;
  align-items: center;
}

.prop-key {
  color: #435468;
  height: 20px;
  font-size: 12px;
  font-weight: bold;
  border-radius: 0 4px 0 4px;
  padding: 0 11px 0 7px;
  display: flex;
  align-items: center;
  background-color: #ffffff;
}

.prop-value {
  background-color: #d7b9b9;
  font-size: 12px;
  border-radius: 0 4px 4px 0;
  color: #734545;
  height: 20px;
  padding: 0 7px;
  display: flex;
  align-items: center;
  /*  超出省略*/
  width: 27px;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.add-view {
  margin-right: 10px;
}

.close-view {
  position: absolute;
  top: -7px;
  right: -12px;
  font-size: 17px;
  color: #fd1d1d;
}
</style>
